package com.zee.admin.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zee.admin.dao.SysRoleDao;
import com.zee.admin.entity.SysRole;
import com.zee.admin.enums.SuperAdminEnum;
import com.zee.admin.model.dto.SysRoleDTO;
import com.zee.admin.model.dto.SysRoleListDTO;
import com.zee.admin.model.dto.SysRoleQueryDTO;
import com.zee.admin.model.vo.SysRoleVO;
import com.zee.admin.service.*;
import com.zee.admin.shiro.AdminSecurityUser;
import com.zee.admin.shiro.AdminUserDetail;
import com.zee.common.utils.ConvertUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.List;
import java.util.Map;

@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleDao, SysRole> implements ISysRoleService {
    @Autowired
    private ISysRoleMenuService sysRoleMenuService;
    @Autowired
    private ISysRoleDataScopeService sysRoleDataScopeService;
    @Autowired
    private ISysRoleUserService sysRoleUserService;
    @Autowired
    private ISysDeptService sysDeptService;

    @Override
    public Page<SysRole> page(SysRoleQueryDTO dto) {
        Map<String, Object> params = BeanUtil.beanToMap(dto);
        return baseMapper.selectPage(new Page<>(dto.getPage(), dto.getPageSize()), this.getWrapper(params));
    }

    @Override
    public List<SysRole> list(SysRoleListDTO dto) {
        Map<String, Object> params = BeanUtil.beanToMap(dto);
        return baseMapper.selectList(this.getWrapper(params));
    }

    private LambdaQueryWrapper<SysRole> getWrapper(Map<String, Object> params) {
        AdminUserDetail user = AdminSecurityUser.getUser();
        String roleName = (String) params.get("roleName");

        LambdaQueryWrapper<SysRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(roleName), SysRole::getName, roleName);

        //普通管理员，只能查询所属部门及子部门的数据
        if (user.getSuperAdmin() == SuperAdminEnum.NO.value()) {
            List<Integer> deptIdList = sysDeptService.getSubDeptIdList(user.getDeptId(), true);
            queryWrapper.in(deptIdList != null, SysRole::getDeptId, deptIdList);
        }

        return queryWrapper;
    }

    @Override
    public SysRoleVO info(Integer id) {
        SysRole sysRole = baseMapper.selectById(id);

        return ConvertUtil.sourceToTarget(sysRole, SysRoleVO.class);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(SysRoleDTO dto) {
        SysRole sysRole = ConvertUtil.sourceToTarget(dto, SysRole.class);
        //设置角色是哪个部门创建的
        sysRole.setDeptId(AdminSecurityUser.getDeptId());
        //保存角色
        this.save(sysRole);

        //保存角色菜单关系
        sysRoleMenuService.saveOrUpdate(sysRole.getId(), dto.getMenuIdList());

        //保存角色数据权限关系
        sysRoleDataScopeService.saveOrUpdate(sysRole.getId(), dto.getDeptIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysRoleDTO dto) {
        SysRole sysRole = ConvertUtil.sourceToTarget(dto, SysRole.class);

        //更新角色
        this.updateById(sysRole);

        //更新角色菜单关系
        sysRoleMenuService.saveOrUpdate(sysRole.getId(), dto.getMenuIdList());

        //更新角色数据权限关系
        sysRoleDataScopeService.saveOrUpdate(sysRole.getId(), dto.getDeptIdList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Integer[] ids) {
        //删除角色
        baseMapper.deleteBatchIds(Arrays.asList(ids));

        //删除角色用户关系
        sysRoleUserService.deleteByRoleIds(ids);

        //删除角色菜单关系
        sysRoleMenuService.deleteByRoleIds(ids);

        //删除角色数据权限关系
        sysRoleDataScopeService.deleteByRoleIds(ids);
    }

}